package edu.pku.sei.transformation.qvt.engine.modelmorf;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import edu.pku.sei.transformation.editor.model.AtomicTransformation;
import edu.pku.sei.transformation.editor.model.MetaModel;
import edu.pku.sei.transformation.editor.model.ModelType;
import edu.pku.sei.transformation.editor.model.TypedModel;
import edu.pku.sei.transformation.editor.model.execution.Model;
import edu.pku.sei.transformation.editor.model.execution.Pin;
import edu.pku.sei.transformation.editor.model.execution.TransformationExecution;
import edu.pku.sei.transformation.engine.IEngineAdapter;
import edu.pku.sei.transformation.engine.IEngineExtraData;
import edu.pku.sei.transformation.engine.IEngineRunner;
import edu.pku.sei.transformation.qvt.adapter.TransformationAdapter;
import edu.pku.sei.transformation.qvt.codegen.QVTGenerator;



public class ModelMorfAdapter implements IEngineAdapter {

	@Override
	public IEngineRunner getRunner(TransformationExecution execution) throws Exception {
		ModelMorfRunner runner = new ModelMorfRunner();
		if (!(execution.getTransformation() instanceof AtomicTransformation)) {
			throw new Exception("not support composite transformation");
		}
		
		TypedModel target = execution.getDirection();
		runner.targetDomain = target.getName();
		if (target == null) {
			throw new Exception("not define target");
		}
		for(TypedModel typedModel : execution.getTransformation().getTypedModel()) {
			ModelType modelType = (ModelType) typedModel.getType();
			MetaModel metaModel = (MetaModel) modelType.getType();
			File metaModelFile = new File(metaModel.getFilePath().trim()).getAbsoluteFile();
			runner.metaModel.put(modelType.getName(), metaModelFile);
			
		}
//		for (Pin pin : execution.getActualParameters()) {
//			Model model=null;
//			for (Object m : pin.getOutgoings()) {
//				if (m instanceof ObjectFlow) {
//					model = (Model) ((ObjectFlow)m).getTarget();
//				}
//			}
//			for (Object m : pin.getIncomings()) {
//				if (m instanceof ObjectFlow) {
//					model = (Model) ((ObjectFlow)m).getSource();
//				}
//			}
//			File modelFile = new File(model.getFile().trim()).getAbsoluteFile();
//			runner.model.put(pin.getFormalParameter().getName(), modelFile);
//				
//		}
		for (Pin pin : execution.getActualParameters()) {
			if (pin.isDataReady() && pin.getData() instanceof Model) {
				Model model = (Model) pin.getData();
				File modelFile = new File(model.getFile().trim()).getAbsoluteFile();
				runner.model.put(pin.getFormalParameter().getName(), modelFile);
			}
		}
		//ModelMorfExtraData extradata = (ModelMorfExtraData) execution.getExtraData();
		File qvtfile;
		qvtfile = new File("temp\\"+execution.getTransformation().getName()+".qvt").getAbsoluteFile();
//		if (extradata.getQvtFileName() != null && !extradata.getQvtFileName().equals("")) {
//			qvtfile = new File("temp\\"+extradata.getQvtFileName()).getAbsoluteFile();
//		} else {
//			qvtfile = new File("temp\\"+execution.getTransformation().getName()+".qvt").getAbsoluteFile();
//		}
		
		runner.qvtSpecificationFile = qvtfile;
		QVTGenerator gen = new QVTGenerator();
		String rule = gen.generate(new TransformationAdapter((AtomicTransformation) execution.getTransformation()));
		FileWriter fw;
		try {
			fw = new FileWriter(runner.qvtSpecificationFile);
			fw.write(rule, 0, rule.length());
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		runner.executionMode = execution.getModeString();
		runner.transformationName = execution.getTransformation().getName();
		
		return runner;
	}

	@Override
	public IEngineExtraData getExtraData() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getID() {
		return "ModelMorf";
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return null;
	}
}
